package com.vvv.designpattern.synchronizedpattern;

/**
 * @author vvv
 * @date 2023-10-15 12 33
 * discription
 */
public class GuardedSuspensionWithTimeout {
    public static void main(String[] args) {
        GuardedObjectWithTimeout guardedObject = new GuardedObjectWithTimeout();
        new Thread(() -> {
            System.out.println("t1 等待结果");
            Object o = guardedObject.get(2000);
            System.out.println("t1" + o);
        }, "t1").start();
        new Thread(() -> {
            System.out.println("t2 开始下载");
            try {
                // 模拟下载
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("t2 下载完成");
            guardedObject.complete("下载结果");
        }, "t2").start();
    }
}
class GuardedObjectWithTimeout {
    private Object response;

    public Object get(long timeout) {
        synchronized (this) {
            // 开始时间
            long beginTime = System.currentTimeMillis(); // 15:00:00
            // 经历的时间
            long passedTime = 0;
            // while 循环防止被虚假唤醒
            while (response == null) {
                // 剩余的等待时间
                long waitTime = timeout - passedTime; // 2s 1s
                if (waitTime <= 0) {
                    break;
                }
                try {
                    this.wait(waitTime); // 15:01 被虚假唤醒
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                // 经历的时间
                passedTime = System.currentTimeMillis() - beginTime; //15:00:01 1s
            }
            return response;
        }
    }

    public void complete(Object response) {
        synchronized (this) {
            this.response = response;
            this.notifyAll();
        }
    }

    @Override
    public String toString() {
        return "GuardedObject{" +
                "response=" + response +
                '}';
    }
}



